﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.Extensions.Configuration;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using Newtonsoft.Json.Serialization;
using NP.BPMReportPlatform.BuyerScarletInformation.Dto;
using NP.BPMReportPlatform.DBHelper;
using NP.BPMReportPlatform.Entities.BPM_Business;
using NP.BPMReportPlatform.Entities.BPM_Engine;
using NP.Enterprise.Utils.Http;
using SqlSugar;

namespace NP.BPMReportPlatform.RecurringJobs
{
    public class BuyerScarletInformationJob : BpmReportPlatformRecurringJob, IBuyerScarletInformationJob
    {
        private readonly SqlSugarClient _db, _dbEngine;

        // private readonly ILogger<BuyerScarletInformationService> _logger;
        private readonly INPRestHttpHelper _httpClient;

        private readonly string _esbUrl;
        private readonly string _esbInvoiceUrl;

        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="sqlSugarAppService"></param>
        /// <param name="httpClient"></param>
        /// <param name="configuration"></param>
        public BuyerScarletInformationJob(ISqlSugarAppService sqlSugarAppService, INPRestHttpHelper httpClient,
            IConfiguration configuration)
        {
            _db = sqlSugarAppService.GetBusinessInstance();
            _dbEngine = sqlSugarAppService.GetEngineInstance();
            _httpClient = httpClient;
            _esbUrl = configuration["Nippon:ESB:ESBCommApi"];
            _esbInvoiceUrl = configuration["Nippon:ESB:ESBInvoiceApi"];
        }

        /// <summary>
        /// 获取发票详情
        /// </summary>
        /// <param name="dto">发票编号/号码</param>
        /// <returns></returns>
        private async Task<Root> QueryInvoiceInfoSendEsb(QueryInvoiceInfoInputDto dto)
        {
            var headers = new Dictionary<string, string>
            {
                {"sourceSystem", "BPMNEW"},
                {"serviceName", "S_XXX_SWGL_QueryInvoiceInfo_S"}
            };
            //  "ESBCommApi": "http://esb-test.nipponpaint.com.cn/esb/comm/api",
            // http://esb.nipponpaint.com.cn/esb/comm/api

            return await _httpClient.ESBPostAsync<Root>(_esbUrl, dto, headers);
        }


        public async Task UpdateCompleteRedInvoiceCode()
        {
            // throw new NotImplementedException();
            // 获取主表中，类型是关联企业的主体
            // 连接查询到所有子行
            var details = await _db
                .Queryable<BuyerScarletInformationFormHeader, BuyerScarletInformationFormDetail, BusinessProcessesNew>(
                    (a, b, c) => a.InstanceNumber == b.InstanceNumber
                                 && a.InstanceNumber == c.InstanceId)
                .Where((a, b, c) => c.IsEnd == true && SqlFunc.IsNullOrEmpty(b.RedInvoiceNumber) && a.AddTime > DateTime.Now.AddMonths(-1) && a.AddTime < DateTime.Now
                // && b.InstanceNumber == "220823000001"
                )
                .Select((a, b, c) => b)
                .ToListAsync();

            if (details.Count > 0)
            {
                foreach (var detail in details)
                {
                    if (string.IsNullOrEmpty(detail.SAPEntryVoucher))
                    {
                        //无法查询
                        continue;
                    }
                    // 20QPS  每50毫秒调用一次，如果是2QPS则500毫秒，根据票易通设置来进行调整
                    // #if DEBUG
                    // Thread.Sleep(50);
                    // #endif

                    if (!string.IsNullOrEmpty(detail.RedInvoiceNumber) || !string.IsNullOrEmpty(detail.RedInvoiceCode))
                    {
                        continue;
                    }

                    var sendRedLetterMain = await _db.Queryable<SendRedLetterInvoiceMain>()
                        .Where(x => x.SellerNumber == detail.ApplySerialNo).FirstAsync();


                    // 处理编号 开头补0，但是结尾不需要-SAP
                    var sapEntryVoucher = detail.SAPEntryVoucher;
                    if (!sapEntryVoucher.StartsWith("0"))
                    {
                        sapEntryVoucher = "0" + sapEntryVoucher;
                    }

                    if (sapEntryVoucher.ToUpper().EndsWith("-SAP"))
                    {
                        sapEntryVoucher = sapEntryVoucher.Replace("-SAP", "");
                    }


                    // 轮询票易通方，获取对应发票的红冲发票信息
                    // 传递业务单号字段
                    var result = await QueryInvoiceInfoSendEsb(new QueryInvoiceInfoInputDto
                    {
                        SalesbillNo = sapEntryVoucher
                    });
                    if (result.code != 1 || result.result.Count == 0)
                    {
                        // 没有数据，未开出红冲发票
                        continue;
                    }

                    // 获取对应值，更新到表单中 InstanceParams表
                    var info = result.result[0].invoiceInfo;
                    detail.RedInvoiceNumber = info.invoiceNo;
                    detail.RedInvoiceCode = info.invoiceCode;
                    detail.RedInvoiceDate = Convert.ToDateTime(info.paperDrawDate); // 开票日期
                    await _db.Updateable(detail).ExecuteCommandAsync();
                    // 更新数据库流程表中对应字段

                    var lineData = await _dbEngine
                        .Queryable<Instances, InstanceParams>((a, b) => a.InstanceId == b.InstanceId)
                        .Where((a, b) => a.Number == detail.InstanceNumber && b.Key == "lineData").Select((a, b) => b)
                        .FirstAsync();

                    var line = JsonConvert.DeserializeObject<JArray>(lineData.Value);

                    if (line != null && line.Count > 0)
                    {
                        // 首先获取对应节点
                        // detail.ApplySerialNo
                        // 可能存在相同的问题
                        var node = line.First(x => x["applySerialNo"].Value<string>() == detail.ApplySerialNo);

                        var redInvoiceNumber = info.invoiceNo;
                        var redInvoiceCode = info.invoiceCode;
                        var redInvoiceDate = Convert.ToDateTime(info.paperDrawDate); // 开票日期


                        node["redInvoiceNumber"] = redInvoiceNumber;
                        node["redInvoiceCode"] = redInvoiceCode;
                        node["redInvoiceDate"] = redInvoiceDate;
                        // node["redLetterNumber"] = sendRedLetterMain != null ? sendRedLetterMain.ApplyTaxNo : "";
                        node["financeVoucherNo"] = detail.FinanceVoucherNo;
                        lineData.Value = JsonConvert.SerializeObject(line, new JsonSerializerSettings()
                        {
                            // 驼峰
                            ContractResolver = new CamelCasePropertyNamesContractResolver()
                        });

                        await _dbEngine.Updateable(lineData).ExecuteCommandAsync();
                    }
                }
            }
        }
    }
}